#include <stdio.h>
#include <stdlib.h>
#include "tcp_server.h"

#include "handshake.h"
#include "aes.h"


static void
_print_key(const char* name, const DH_KEY key) {
	int i;

	printf("%s=\t", name);
	for (i = DH_KEY_LENGTH-1; i>=0; i--) {
		printf("%02x", key[i]);
	}
	printf("\n");
}

extern uint8_t *fromhex(const char *str);
extern char *tohex(const uint8_t *bin, size_t l);

int client(){

	int sFd;
	int sockAddrSize;
	struct sockaddr_in serverAddr;
	char * innerIP = "127.0.0.1";
	char server_msg[20];
	char* client_msg;
	int i;
	MSG_HandShake msg_HandShake;
	DH_KEY client_private, client_public, client_secret, server_public;
	UINT32 client_nonce;
	UINT32 server_nonce;
	aes_encrypt_ctx ctxe;
	aes_decrypt_ctx ctxd;
	uint8_t ibuf[16], obuf[16];
	unsigned char nonce[16];
	UINT32 nonceTemp;
	
	if ((sFd = socket(AF_INET, SOCK_STREAM, 0)) == ERROR) {
		
		return 1;
	}

	sockAddrSize = sizeof(struct sockaddr_in);
	serverAddr.sin_family = AF_INET;
	serverAddr.sin_len = (u_char) sockAddrSize;
	serverAddr.sin_port = htons (SERVER_PORT_NUM);

	if (((serverAddr.sin_addr.s_addr = inet_addr(innerIP)) == ERROR)) {
		return 1;
	}	

	if (connect(sFd, (struct sockaddr *) &serverAddr, sockAddrSize) == ERROR) {
		printf("client connect error.\n");
		shutdown(sFd,0);
		return 1;
	}
	
	//send HELLO_MSG
	msg_HandShake.type = HAND01;
	if (send(sFd, (char *)&msg_HandShake, sizeof(MSG_HandShake), 0) == ERROR) {
		shutdown(sFd,0);
		return 1;
	}
	printf ("client send HAND01\n");
	
	//RECV Public_key_1||nonce_1
	if (recv(sFd, (char *)&msg_HandShake, sizeof(MSG_HandShake), 0) < 0) {
		printf("\t\t tcs_tcp_msg_recv error!\n");
		shutdown(sFd, 0);
		return;
	}
	printf ("client recv HAND02\n");
	if (msg_HandShake.type != HAND02){
		shutdown(sFd,0);
		return 1;
	}

	memcpy(&server_public, &(msg_HandShake.publicKey), sizeof(msg_HandShake.publicKey));
	DH_generate_key_pair(client_public, client_private);
	memcpy(&(msg_HandShake.publicKey), &client_public, sizeof(client_public));
	client_nonce = random();
	msg_HandShake.client_nonce = client_nonce;
	msg_HandShake.type = HAND03;
	
	_print_key("client recv: server_public", server_public);
	_print_key("client: client_public", client_public);
	_print_key("client: client_private", client_private);
	printf ("client: client_nonce %d\n", client_nonce);
	
	//SEND Public_key_2||nonce_1||nonce_2
	if (send(sFd, (char *)&msg_HandShake, sizeof(MSG_HandShake), 0) == ERROR) {
		shutdown(sFd,0);
		return 1;
	}
	printf ("client send HAND03\n");
	
	//RECV secret_key(nonce_2)
	if (recv(sFd, (char *)&msg_HandShake, sizeof(MSG_HandShake), 0) < 0) {
		printf("\t\t tcs_tcp_msg_recv error!\n");
		shutdown(sFd, 0);
		return;
	}
	printf ("client recv HAND04\n");
	if (msg_HandShake.type != HAND04){
		shutdown(sFd, 0);
		return;
	}
	
	DH_generate_key_secret(client_secret, client_private, server_public);
	
	_print_key ("client secret key: ", client_secret);
	
/*	aes_decrypt_key128(fromhex(client_secret), &ctxd);
	memcpy(ibuf, fromhex(msg_HandShake.msg), 16);
	aes_ecb_decrypt(ibuf, obuf, 16, &ctxd);
	
	//UINT32 nonceTemp;
	sprintf(nonceTemp,"%d", *obuf);
	printf ("nonceTemp decrypt is : %d", nonceTemp);
	if (nonceTemp == client_nonce){
		printf ("handshake successful\n");
	}
*/	
	sprintf(nonce,"%x", client_nonce);
	
	
	aes_encrypt_key128(fromhex(client_secret), &ctxe);
	memcpy(ibuf, fromhex(nonce), 16);
	aes_ecb_encrypt(ibuf, obuf, 16, &ctxe);
	printf ("client obuf: %s\n", tohex(obuf, 16));
	printf ("this client_nonce is %d\n", client_nonce);
	
	
	if (strcmp(tohex(obuf, 16), tohex(msg_HandShake.msg, 16)) == 0){
		printf ("handshake successful\n");
	}
	

	
/*	if (send(sFd, (char *) client_msg, 20, 0) == ERROR) {
		shutdown(sFd,0);
		return 1;
	}
	
	if (recv(sFd, (char *) server_msg, 20, 0) == ERROR) {
		printf("client recv error.\n");
		shutdown(sFd,0);
		return 1;
	}
*/
	return 0;
}